// SPDX-License-Identifier: GPL-2.0
/*
 * BiscuitOS SPECIAL DEVICE PAGE on GUP
 *
 * (C) 2024.04.10 BuddyZhang1 <buddy.zhang@aliyun.com>
 * (C) 2024.04.10 BiscuitOS
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>

#define DEV_PATH		"/dev/BiscuitOS"
#define P2P_MMIO_BASE		0x80000000
#define P2P_MMIO_SIZE		0x20000000 /* 512MB */
#define MAP_SIZE		P2P_MMIO_SIZE
#define BISCUITOS_IO		0xBD
#define RECLAIM_PGTABLE		_IO(BISCUITOS_IO, 0x00)

int main()
{
	int fd, dfd;
	void *buffer;

	/* open device */
	fd = open(DEV_PATH, O_RDWR);
	if (fd < 0) {
		printf("ERROR: Can't open %s\n", DEV_PATH);
		return -1;
	}

	/* MMAP */
	buffer = mmap(NULL, MAP_SIZE,
		      PROT_READ | PROT_WRITE,
		      MAP_SHARED,
		      fd,
		      P2P_MMIO_BASE);
	if (buffer == MAP_FAILED) {
		printf("ERROR: MAP_FAILED.\n");
		close(fd);
		return -1;
	}
	printf("BUFFER %#lx\n", (unsigned long)buffer);

	/* FORBIDDEN ACCESS FAKE MMIO */

	/* WRITE OPS TEST */
	write(fd, buffer, 10);

	/* RECLAIM DEVICE PAGE */
	ioctl(fd, RECLAIM_PGTABLE, (unsigned long)buffer);
	/* RECLAIM MEMORY */
	munmap(buffer, MAP_SIZE);
	close(dfd);
	close(fd);

	printf("TEST SUCCED.\n");

	return 0;
}
